#ifndef __HEADER_SM2_H
#define __HEADER_SM2_H

#include "ecc.h"
#include "sm3.h"

struct sm2_signature_ctx {
    unsigned char sig_r[SM3_DIGEST_LENGTH];
    unsigned char sig_s[SM3_DIGEST_LENGTH];
};
typedef struct sm2_signature_ctx SM2_SIG_CTX;

#define SM2_DEFAULT_ID "1234567812345678"

// 预处理
int SM2_compute_message_digest(const unsigned char* msg, size_t msglen,
                               const unsigned char* id, size_t idlen,
                               unsigned char dgst[SM3_DIGEST_LENGTH],
                               EC_KEY*       key);

int SM2_sign(const unsigned char dgst[SM3_DIGEST_LENGTH], SM2_SIG_CTX* rs,
             EC_KEY* private);

int SM2_verify(const unsigned char dgst[SM3_DIGEST_LENGTH], SM2_SIG_CTX* rs,
               EC_KEY* public);

int SM2_encrypt(const unsigned char* in, size_t inlen, unsigned char* out,
                size_t* outlen, EC_KEY* public);

int SM2_decrypt(const unsigned char* in, size_t inlen, unsigned char* out,
                size_t* outlen, EC_KEY* private);

struct sm2_kap_ctx_st {
    EC_KEY*  key;
    EC_POINT rpub;
    EC_POINT R;

    MPI two_pow_w;
    MPI t;

    unsigned char Z[SM3_DIGEST_LENGTH];
    unsigned char rZ[SM3_DIGEST_LENGTH];
    unsigned char checksum[SM3_DIGEST_LENGTH];
    int           do_checksum;
    int           is_initiator;
};
typedef struct sm2_kap_ctx_st SM2_KAP_CTX;

int SM2_KAP_CTX_init(SM2_KAP_CTX* ctx, EC_KEY* key, EC_POINT* peer_pubkey,
                     const char* id, size_t idlen, const char* rid,
                     size_t ridlen, int is_initiator, int do_checksum);

int SM2_KAP_prepare(SM2_KAP_CTX* ctx, unsigned char R[SM2_PUBKEY_LEN]);

int SM2_KAP_compute_key(SM2_KAP_CTX* ctx, unsigned char R[SM2_PUBKEY_LEN],
                        unsigned char* key, size_t keylen,
                        unsigned char checksum[SM3_DIGEST_LENGTH]);

int SM2_KAP_final_check(SM2_KAP_CTX*        ctx,
                        const unsigned char checksum[SM3_DIGEST_LENGTH]);

void SM2_KAP_CTX_cleanup(SM2_KAP_CTX* ctx);

#endif  // __HEADER_SM2_H